package com.adee.netty.demo;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;

import java.net.URI;
import java.nio.charset.StandardCharsets;

public class NettyClient {
    public static void main(String[] args) {
        // 客户端需要一个事件循环组
        NioEventLoopGroup group = new NioEventLoopGroup();

        try {
            // 创建客户端启动对象
            // 注意客户端使用的不是ServerBootStrap，而是BootStrap
            Bootstrap bootstrap = new Bootstrap();

            // 设置相关参数
            bootstrap.group(group) // 设置线程组
                    .channel(NioSocketChannel.class) // 设置客户端通道的实现类（反射）
                    .option(ChannelOption.CONNECT_TIMEOUT_MILLIS,1000) // 建立连接超时时间
                    .handler(new ChannelInitializer<SocketChannel>() { //

                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new HttpClientCodec());
                            ch.pipeline().addLast("aggre", new HttpObjectAggregator(10*1024*1024));
                            ch.pipeline().addLast("decompressor", new HttpContentDecompressor());
                            // ch.pipeline().addLast(new NettyClientHandler()); // 加入自己的handler
                            ch.pipeline().addLast("busi", new ChannelInboundHandlerAdapter(){
                                // 读取服务器响应
                                @Override
                                public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                    if(msg instanceof FullHttpResponse) {
                                        FullHttpResponse response = (FullHttpResponse)msg;
                                        System.out.println("服务器返回：");
                                        System.out.println(response.headers());
                                        ByteBuf content = response.content();
                                        System.out.println(content.toString(CharsetUtil.UTF_8));
                                        content.release();
                                    } else {
                                        System.out.println("服务器返回的不是FullHttpResponse," + msg);
                                    }
                                }
                            });
                        }
                    });
            System.out.println("客户端 ok...");
            // 启动客户端去连接服务器端
            // 关于ChannelFuture要分析，涉及到netty的异步模型
            ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6668).sync();
            // channelFuture.channel().writeAndFlush("aaaaa"); // 在tcp连接上发送数据
            // 发送http请求
            URI uri = new URI("/test");
            String msg = "hello";
            DefaultFullHttpRequest request = new DefaultFullHttpRequest(
                    HttpVersion.HTTP_1_1,
                    HttpMethod.GET,
                    uri.toASCIIString(),
                    Unpooled.wrappedBuffer(msg.getBytes(StandardCharsets.UTF_8))
            );
            request.headers().set(HttpHeaderNames.HOST, "127.0.0.1");
            request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
            request.headers().set(HttpHeaderNames.CONTENT_LENGTH, request.content().readableBytes());
            channelFuture.channel().write(request);
            channelFuture.channel().flush();
            // 给关闭通道进行监听
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            group.shutdownGracefully(); //
        }

    }
}
